<template><div><p>本文档最新版为 <a href="https://learnku.com/docs/laravel/10.x" target="_blank" rel="noopener noreferrer">10.x</a>，旧版本可能放弃维护，推荐阅读最新版！</p>
<h2 id="laravel-的用户授权系统" tabindex="-1"><a class="header-anchor" href="#laravel-的用户授权系统"><span>Laravel 的用户授权系统</span></a></h2>
<ul>
<li><a href="#introduction">简介</a></li>
<li><a href="#gates">Gates</a>
<ul>
<li><a href="#writing-gates">编写 Gates</a></li>
<li><a href="#authorizing-actions-via-gates">授权动作</a></li>
</ul>
</li>
<li><a href="#creating-policies">创建策略</a>
<ul>
<li><a href="#generating-policies">生成策略</a></li>
<li><a href="#registering-policies">注册策略</a></li>
</ul>
</li>
<li><a href="#writing-policies">编写策略</a>
<ul>
<li><a href="#policy-methods">策略方法</a></li>
<li><a href="#methods-without-models">不使用模型方法</a></li>
<li><a href="#policy-filters">策略过滤器</a></li>
</ul>
</li>
<li><a href="#authorizing-actions-using-policies">使用策略授权动作</a>
<ul>
<li><a href="#via-the-user-model">通过用户模型</a></li>
<li><a href="#via-middleware">通过中间件</a></li>
<li><a href="#via-controller-helpers">通过控制器辅助函数</a></li>
<li><a href="#via-blade-templates">通过 Blade 模板</a></li>
</ul>
</li>
</ul>
<h2 id="简介" tabindex="-1"><a class="header-anchor" href="#简介"><span>简介</span></a></h2>
<p>除了内置开箱即用的 <a href="https://learnku.com/docs/laravel/5.5/authentication" target="_blank" rel="noopener noreferrer">用户认证</a> 服务外，Laravel 还提供一种更简单的方式来处理用户授权动作。类似用户认证，Laravel 有 2 种主要方式来实现用户授权：gates 和策略。</p>
<p>可以把 gates 和策略类比于路由和控制器。 Gates 提供了一个简单的、基于闭包的方式来授权认证。策略则和控制器类似，在特定的模型或者资源中通过分组来实现授权认证的逻辑。我们先来看看 gates，然后再看策略。</p>
<p>在你的应用中，不要将 gates 和策略当作相互排斥的方式。大部分应用很可能同时包含 gates 和策略，并且能很好的工作。Gates 大部分应用在模型和资源无关的地方，比如查看管理员的面板。与之相反，策略应该用在特定的模型或者资源中。</p>
<h2 id="gates" tabindex="-1"><a class="header-anchor" href="#gates"><span>Gates</span></a></h2>
<h3 id="编写-gates" tabindex="-1"><a class="header-anchor" href="#编写-gates"><span>编写 Gates</span></a></h3>
<p>Gates 是用来决定用户是否授权执行给定的动作的闭包函数，并且典型的做法是在 <code v-pre>App\Providers\AuthServiceProvider</code> 类中使用 <code v-pre>Gate</code> facade 定义。Gates 接受一个用户实例作为第一个参数，并且可以接受可选参数，比如 相关的 Eloquent 模型：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * 注册任意用户认证、用户授权服务。</span>
<span class="line"> *</span>
<span class="line"> * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">void</span></span></span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">boot</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">registerPolicies</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token class-name static-context">Gate</span><span class="token operator">::</span><span class="token function">define</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'update-post'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$user</span><span class="token punctuation">,</span> <span class="token variable">$post</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token variable">$user</span><span class="token operator">-></span><span class="token property">id</span> <span class="token operator">==</span> <span class="token variable">$post</span><span class="token operator">-></span><span class="token property">user_id</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Gates 也可以使用 <code v-pre>Class@method</code> 风格的回调字符串来定义，比如控制器:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * Register any authentication / authorization services.</span>
<span class="line"> *</span>
<span class="line"> * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">void</span></span></span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">boot</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">registerPolicies</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token class-name static-context">Gate</span><span class="token operator">::</span><span class="token function">define</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'update-post'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'PostPolicy@update'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="资源-gates" tabindex="-1"><a class="header-anchor" href="#资源-gates"><span>资源 Gates</span></a></h4>
<p>你还可以使用 <code v-pre>resource</code> 方法一次性定义多个 Gate 功能:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Gate</span><span class="token operator">::</span><span class="token function">resource</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'posts'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'PostPolicy'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>这与手动编写以下 Gate 定义相同：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Gate</span><span class="token operator">::</span><span class="token function">define</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'posts.view'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'PostPolicy@view'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token class-name static-context">Gate</span><span class="token operator">::</span><span class="token function">define</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'posts.create'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'PostPolicy@create'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token class-name static-context">Gate</span><span class="token operator">::</span><span class="token function">define</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'posts.update'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'PostPolicy@update'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token class-name static-context">Gate</span><span class="token operator">::</span><span class="token function">define</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'posts.delete'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'PostPolicy@delete'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>默认情况下将会定义 <code v-pre>view</code> ， <code v-pre>create</code> ， <code v-pre>update</code> ，和 <code v-pre>delete</code> 功能。 通过将数组作为第三个参数传递给 <code v-pre>resource</code> 方法，您可以覆盖或添加新功能到默认的功能。 数组的键定义能力的名称，而值定义方法名称。 例如，以下代码将创建两个新的Gate定义： <code v-pre>posts.image</code> 和 <code v-pre>posts.photo</code> ：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Gate</span><span class="token operator">::</span><span class="token function">resource</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'posts'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'PostPolicy'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'image'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'updateImage'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'photo'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'updatePhoto'</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="授权动作" tabindex="-1"><a class="header-anchor" href="#授权动作"><span>授权动作</span></a></h3>
<p>使用 gates 来授权动作时，应使用 <code v-pre>allows</code> 或 <code v-pre>denies</code> 方法。注意你并不需要传递当前认证通过的用户给这些方法。Laravel 会自动处理好传入的用户，然后传递给 gate 闭包函数：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name static-context">Gate</span><span class="token operator">::</span><span class="token function">allows</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'update-post'</span><span class="token punctuation">,</span> <span class="token variable">$post</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// 当前用户可以更新博客...</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name static-context">Gate</span><span class="token operator">::</span><span class="token function">denies</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'update-post'</span><span class="token punctuation">,</span> <span class="token variable">$post</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// 当前用户不能更新博客...</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果需要指定一个特定用户是否可以访问某个动作，可以使用 <code v-pre>Gate</code> facade 中的 <code v-pre>forUser</code> 方法：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name static-context">Gate</span><span class="token operator">::</span><span class="token function">forUser</span><span class="token punctuation">(</span><span class="token variable">$user</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">allows</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'update-post'</span><span class="token punctuation">,</span> <span class="token variable">$post</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// 指定用户可以更新博客...</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name static-context">Gate</span><span class="token operator">::</span><span class="token function">forUser</span><span class="token punctuation">(</span><span class="token variable">$user</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">denies</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'update-post'</span><span class="token punctuation">,</span> <span class="token variable">$post</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// 指定用户不能更新博客...</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="创建策略" tabindex="-1"><a class="header-anchor" href="#创建策略"><span>创建策略</span></a></h2>
<h3 id="生成策略" tabindex="-1"><a class="header-anchor" href="#生成策略"><span>生成策略</span></a></h3>
<p>策略是在特定模型或者资源中组织授权逻辑的类。例如，如果你的应用是一个博客，会有一个 <code v-pre>Post</code> 模型和一个相应的 <code v-pre>PostPolicy</code> 来授权用户动作，比如创建或者更新博客。</p>
<p>可以使用 <code v-pre>make:policy</code> <a href="https://learnku.com/docs/laravel/5.5/artisan" target="_blank" rel="noopener noreferrer">artisan 命令</a> 来生成策略。生成的策略将放置在 <code v-pre>app/Policies</code> 目录。如果在你的应用中不存在这个目录，那么 Laravel 会自动创建：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">php artisan make<span class="token punctuation">:</span>policy PostPolicy</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p><code v-pre>make:policy</code> 会生成空的策略类。如果希望生成的类包含基本的「CRUD」策略方法， 可以在使用命令时指定 <code v-pre>--model</code> 选项：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">php artisan make<span class="token punctuation">:</span>policy PostPolicy <span class="token operator">--</span>model<span class="token operator">=</span>Post</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><blockquote>
<p>{tip} 所有授权策略会通过 Laravel <a href="https://learnku.com/docs/laravel/5.5/container" target="_blank" rel="noopener noreferrer">服务容器</a> 解析，意指你可以在授权策略的构造器对任何需要的依赖使用类型提示，它们将会被自动注入。</p>
</blockquote>
<h3 id="注册策略" tabindex="-1"><a class="header-anchor" href="#注册策略"><span>注册策略</span></a></h3>
<p>一旦该授权策略存在，需要将它进行注册。新的 Laravel 应用中包含的 <code v-pre>AuthServiceProvider</code> 包含了一个 <code v-pre>policies</code> 属性，可将各种模型对应至管理它们的授权策略。注册一个策略将引导 Laravel 在授权动作访问指定模型时使用何种策略：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Providers</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Post</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Policies<span class="token punctuation">\</span>PostPolicy</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Gate</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Foundation<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Providers<span class="token punctuation">\</span>AuthServiceProvider</span> <span class="token keyword">as</span> ServiceProvider<span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">AuthServiceProvider</span> <span class="token keyword">extends</span> <span class="token class-name">ServiceProvider</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 应用的策略映射。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@var</span> <span class="token class-name"><span class="token keyword">array</span></span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">protected</span> <span class="token variable">$policies</span> <span class="token operator">=</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token class-name static-context">Post</span><span class="token operator">::</span><span class="token keyword">class</span> <span class="token operator">=></span> <span class="token class-name static-context">PostPolicy</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 注册任意用户认证、用户授权服务。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">void</span></span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">boot</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">registerPolicies</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token comment">//</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="编写策略" tabindex="-1"><a class="header-anchor" href="#编写策略"><span>编写策略</span></a></h2>
<h3 id="策略方法" tabindex="-1"><a class="header-anchor" href="#策略方法"><span>策略方法</span></a></h3>
<p>一旦授权策略被生成且注册，我们就可以为授权的每个动作添加方法。例如，让我们在 <code v-pre>PostPolicy</code> 中定义一个 <code v-pre>update</code> 方法，它会判断指定的 <code v-pre>User</code> 是否可以更新指定的 <code v-pre>Post</code> 实例。</p>
<p><code v-pre>update</code> 方法接受 <code v-pre>User</code> 和 <code v-pre>Post</code> 实例作为参数，并且应当返回 <code v-pre>true</code> 或 <code v-pre>false</code> 来指明用户是否授权更新指定的 <code v-pre>Post</code>。因此，这个例子中，我们判断用户的 <code v-pre>id</code> 是否和 post 中的 <code v-pre>user_id</code> 匹配：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Policies</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>User</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Post</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">PostPolicy</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 判断指定博客能否被用户更新。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@param</span>  <span class="token class-name"><span class="token punctuation">\</span>App<span class="token punctuation">\</span>User</span>  <span class="token parameter">$user</span></span>
<span class="line">     * <span class="token keyword">@param</span>  <span class="token class-name"><span class="token punctuation">\</span>App<span class="token punctuation">\</span>Post</span>  <span class="token parameter">$post</span></span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">bool</span></span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">update</span><span class="token punctuation">(</span><span class="token class-name type-declaration">User</span> <span class="token variable">$user</span><span class="token punctuation">,</span> <span class="token class-name type-declaration">Post</span> <span class="token variable">$post</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token variable">$user</span><span class="token operator">-></span><span class="token property">id</span> <span class="token operator">===</span> <span class="token variable">$post</span><span class="token operator">-></span><span class="token property">user_id</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>你可以继续为此授权策略定义额外的方法，作为各种权限所需要的授权。例如，你可以定义 <code v-pre>view</code> 或 <code v-pre>delete</code> 方法来授权 <code v-pre>Post</code> 的多种行为。可以为自定义策略方法使用自己喜欢的名字。</p>
<blockquote>
<p>{tip} 如果在 Artisan 控制台生成策略时使用 <code v-pre>--model</code> 选项，会自动包含<code v-pre>view</code>、<code v-pre>create</code>、<code v-pre>update</code> 和 <code v-pre>delete</code> 动作。</p>
</blockquote>
<h3 id="不包含模型方法" tabindex="-1"><a class="header-anchor" href="#不包含模型方法"><span>不包含模型方法</span></a></h3>
<p>一些策略方法只接受当前认证通过的用户作为参数而不用传入授权相关的模型实例。最普遍的应用场景就是授权 <code v-pre>create</code> 动作。例如，如果正在创建一篇博客，你可能希望检查一下当前用户是否有权创建博客。</p>
<p>当定义一个不需要传入模型实例的策略方法时，比如 <code v-pre>create</code> 方法，你需要定义这个方法只接受已授权的用户作为参数：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * 判断指定用户是否可以创建博客。</span>
<span class="line"> *</span>
<span class="line"> * <span class="token keyword">@param</span>  <span class="token class-name"><span class="token punctuation">\</span>App<span class="token punctuation">\</span>User</span>  <span class="token parameter">$user</span></span>
<span class="line"> * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">bool</span></span></span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">create</span><span class="token punctuation">(</span><span class="token class-name type-declaration">User</span> <span class="token variable">$user</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">//</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="策略过滤器" tabindex="-1"><a class="header-anchor" href="#策略过滤器"><span>策略过滤器</span></a></h3>
<p>对特定用户，你可能希望通过指定的策略授权所有动作。 要达到这个目的，可以在策略中定义一个 <code v-pre>before</code> 方法。<code v-pre>before</code> 方法会在策略中其它所有方法之前执行，这样提供了一种方式来授权动作而不是指定的策略方法来执行判断。这个功能最常见的场景是授权应用的管理员可以访问所有动作：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">before</span><span class="token punctuation">(</span><span class="token variable">$user</span><span class="token punctuation">,</span> <span class="token variable">$ability</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$user</span><span class="token operator">-></span><span class="token function">isSuperAdmin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token constant boolean">true</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果你想拒绝用户所有的授权，你应该在 <code v-pre>before</code> 方法中返回 <code v-pre>false</code>。如果返回的是 <code v-pre>null</code>，则通过其它的策略方法来决定授权与否。</p>
<h2 id="使用策略授权动作" tabindex="-1"><a class="header-anchor" href="#使用策略授权动作"><span>使用策略授权动作</span></a></h2>
<h3 id="通过用户模型" tabindex="-1"><a class="header-anchor" href="#通过用户模型"><span>通过用户模型</span></a></h3>
<p>Laravel 应用内置的 <code v-pre>User</code> 模型包含 2 个有用的方法来授权动作：<code v-pre>can</code> 和 <code v-pre>cant</code>。<code v-pre>can</code> 方法需要指定授权的动作和相关的模型。例如，判定一个用户是否授权更新指定的 <code v-pre>Post</code> 模型：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$user</span><span class="token operator">-></span><span class="token function">can</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'update'</span><span class="token punctuation">,</span> <span class="token variable">$post</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">//</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果指定模型的 <a href="#registering-policies">策略已被注册</a>，<code v-pre>can</code> 方法会自动调用核实的策略方法并且返回 boolean 值。如果没有策略注册到这个模型，<code v-pre>can</code> 方法会尝试调用和动作名相匹配的基于闭包的 Gate。</p>
<h4 id="不需要指定模型的动作" tabindex="-1"><a class="header-anchor" href="#不需要指定模型的动作"><span>不需要指定模型的动作</span></a></h4>
<p>记住，一些动作，比如 <code v-pre>create</code> 并不需要指定模型实例。在这种情况下，可传递一个类名给 <code v-pre>can</code> 方法。当授权动作时，这个类名将被用来判断使用哪个策略：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Post</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$user</span><span class="token operator">-></span><span class="token function">can</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'create'</span><span class="token punctuation">,</span> <span class="token class-name static-context">Post</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// 执行相关策略中的「create」方法...</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="通过中间件" tabindex="-1"><a class="header-anchor" href="#通过中间件"><span>通过中间件</span></a></h3>
<p>Laravel 包含一个可以在请求到达路由或控制器之前就进行动作授权的中间件。默认，<code v-pre>Illuminate\Auth\Middleware\Authorize</code> 中间件被指定到 <code v-pre>App\Http\Kernel</code> 类中 <code v-pre>can</code> 键上。我们用一个授权用户更新博客的例子来讲解 <code v-pre>can</code> 中间件的使用：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Post</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/post/{post}'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token class-name type-declaration">Post</span> <span class="token variable">$post</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// 当前用户可以更新博客...</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">middleware</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'can:update,post'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>在这个例子中，我们传递给 <code v-pre>can</code> 中间件 2 个参数。第一个是需要授权的动作的名称，第二个是我们希望传递给策略方法的路由参数。这里因为使用了 <a href="https://learnku.com/docs/laravel/5.5/routing#implicit-binding" target="_blank" rel="noopener noreferrer">隐式模型绑定</a>，一个 <code v-pre>Post</code> 会被传递给策略方法。如果用户不被授权访问指定的动作，这个中间件会生成带有 <code v-pre>403</code> 状态码的 HTTP 响应。</p>
<h4 id="不需要指定模型的动作-1" tabindex="-1"><a class="header-anchor" href="#不需要指定模型的动作-1"><span>不需要指定模型的动作</span></a></h4>
<p>同样的，一些动作，比如 <code v-pre>create</code>，并不需要指定模型实例。在这种情况下，可传递一个类名给中间件。当授权动作时，这个类名将被用来判断使用哪个策略：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">post</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/post'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// 当前用户可以创建博客...</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">middleware</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'can:create,App\Post'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="通过控制器辅助函数" tabindex="-1"><a class="header-anchor" href="#通过控制器辅助函数"><span>通过控制器辅助函数</span></a></h3>
<p>除了在 <code v-pre>User</code> 模型中提供辅助方法外，Laravel 也为所有继承了 <code v-pre>App\Http\Controllers\Controller</code> 基类的控制器提供了一个有用的 <code v-pre>authorize</code> 方法。和 <code v-pre>can</code> 方法类似，这个方法接收需要授权的动作和相关的模型作为参数。如果动作不被授权，<code v-pre>authorize</code> 方法会抛出 <code v-pre>Illuminate\Auth\Access\AuthorizationException</code> 异常，然后被 Laravel 默认的异常处理器转化为带有 <code v-pre>403</code> 状态码的 HTTP 响应：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Controllers</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Post</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Request</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Controllers<span class="token punctuation">\</span>Controller</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">PostController</span> <span class="token keyword">extends</span> <span class="token class-name">Controller</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 更新指定博客。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@param</span>  <span class="token class-name">Request</span>  <span class="token parameter">$request</span></span>
<span class="line">     * <span class="token keyword">@param</span>  <span class="token class-name">Post</span>  <span class="token parameter">$post</span></span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name">Response</span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">update</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">,</span> <span class="token class-name type-declaration">Post</span> <span class="token variable">$post</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">authorize</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'update'</span><span class="token punctuation">,</span> <span class="token variable">$post</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token comment">// 当前用户可以更新博客...</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="不需要指定模型的动作-2" tabindex="-1"><a class="header-anchor" href="#不需要指定模型的动作-2"><span>不需要指定模型的动作</span></a></h4>
<p>和之前讨论的一样，一些动作，比如 <code v-pre>create</code>，并不需要指定模型实例。在这种情况下，可传递一个类名给 <code v-pre>authorize</code> 方法。当授权动作时，这个类名将被用来判断使用哪个策略：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * 新建博客</span>
<span class="line"> *</span>
<span class="line"> * <span class="token keyword">@param</span>  <span class="token class-name">Request</span>  <span class="token parameter">$request</span></span>
<span class="line"> * <span class="token keyword">@return</span> <span class="token class-name">Response</span></span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">create</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">authorize</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'create'</span><span class="token punctuation">,</span> <span class="token class-name static-context">Post</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token comment">// 当前用户可以新建博客...</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="通过-blade-模板" tabindex="-1"><a class="header-anchor" href="#通过-blade-模板"><span>通过 Blade 模板</span></a></h3>
<p>当编写 Blade 模板时，你可能希望页面的指定部分只展示给允许授权访问指定动作的用户。 例如，你可能希望只展示更新表单给有权更新博客的用户。这种情况下，你可以直接使用 <code v-pre>@can</code> 和 <code v-pre>@cannot</code> 指令。</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">@<span class="token function">can</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'update'</span><span class="token punctuation">,</span> <span class="token variable">$post</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">&lt;</span><span class="token operator">!</span><span class="token operator">--</span> 当前用户可以更新博客 <span class="token operator">--</span><span class="token operator">></span></span>
<span class="line">@<span class="token function">elsecan</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'create'</span><span class="token punctuation">,</span> <span class="token variable">$post</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">&lt;</span><span class="token operator">!</span><span class="token operator">--</span> 当前用户可以新建博客 <span class="token operator">--</span><span class="token operator">></span></span>
<span class="line">@endcan</span>
<span class="line"></span>
<span class="line">@<span class="token function">cannot</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'update'</span><span class="token punctuation">,</span> <span class="token variable">$post</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">&lt;</span><span class="token operator">!</span><span class="token operator">--</span> 当前用户不可以更新博客 <span class="token operator">--</span><span class="token operator">></span></span>
<span class="line">@<span class="token function">elsecannot</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'create'</span><span class="token punctuation">,</span> <span class="token variable">$post</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">&lt;</span><span class="token operator">!</span><span class="token operator">--</span> 当前用户不可以新建博客 <span class="token operator">--</span><span class="token operator">></span></span>
<span class="line">@endcannot</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>这些指令在编写 <code v-pre>@if</code> 和 <code v-pre>@unless</code> 时提供了方便的缩写。<code v-pre>@can</code> 和 <code v-pre>@cannot</code> 各自转化为如下声明：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">@<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name static-context">Auth</span><span class="token operator">::</span><span class="token function">user</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">can</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'update'</span><span class="token punctuation">,</span> <span class="token variable">$post</span><span class="token punctuation">)</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">&lt;</span><span class="token operator">!</span><span class="token operator">--</span> 当前用户可以更新博客 <span class="token operator">--</span><span class="token operator">></span></span>
<span class="line">@<span class="token keyword">endif</span></span>
<span class="line"></span>
<span class="line">@<span class="token function">unless</span> <span class="token punctuation">(</span><span class="token class-name static-context">Auth</span><span class="token operator">::</span><span class="token function">user</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">can</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'update'</span><span class="token punctuation">,</span> <span class="token variable">$post</span><span class="token punctuation">)</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">&lt;</span><span class="token operator">!</span><span class="token operator">--</span> 当前用户不可以更新博客 <span class="token operator">--</span><span class="token operator">></span></span>
<span class="line">@endunless</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="不需要指定模型的动作-3" tabindex="-1"><a class="header-anchor" href="#不需要指定模型的动作-3"><span>不需要指定模型的动作</span></a></h4>
<p>和大部分其它的授权方法类似，当动作不需要模型实例时，你可以传递一个类名给 <code v-pre>@can</code> 和 <code v-pre>@cannot</code> 指令：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">@<span class="token function">can</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'create'</span><span class="token punctuation">,</span> <span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>Post</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">&lt;</span><span class="token operator">!</span><span class="token operator">--</span> 当前用户可以新建博客 <span class="token operator">--</span><span class="token operator">></span></span>
<span class="line">@endcan</span>
<span class="line"></span>
<span class="line">@<span class="token function">cannot</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'create'</span><span class="token punctuation">,</span> <span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>Post</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">&lt;</span><span class="token operator">!</span><span class="token operator">--</span> 当前用户不可以新建博客 <span class="token operator">--</span><span class="token operator">></span></span>
<span class="line">@endcannot</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="译者署名" tabindex="-1"><a class="header-anchor" href="#译者署名"><span>译者署名</span></a></h2>
<table>
<thead>
<tr>
<th>用户名</th>
<th>头像</th>
<th>职能</th>
<th>签名</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://github.com/iwzh" target="_blank" rel="noopener noreferrer">@iwzh</a></td>
<td><img src="https://cdn.learnku.com/uploads/avatars/3762_1456807721.jpeg?imageView2/1/w/200/h/200" alt="200"></td>
<td>翻译</td>
<td>码不能停 <a href="https://github.com/iwzh" target="_blank" rel="noopener noreferrer">@iwzh</a> at Github</td>
</tr>
</tbody>
</table>
<hr>
<blockquote>
<p>{note} 欢迎任何形式的转载，但请务必注明出处，尊重他人劳动共创开源社区。</p>
<p>转载请注明：本文档由 Laravel China 社区 <a href="https://laravel-china.org/" target="_blank" rel="noopener noreferrer">laravel-china.org</a> 组织翻译，详见 <a href="https://learnku.com/laravel/t/5756/laravel-55-document-translation-call-come-and-join-the-translation" target="_blank" rel="noopener noreferrer">翻译召集帖</a>。</p>
<p>文档永久地址： <a href="https://learnku.com/docs/laravel" target="_blank" rel="noopener noreferrer">《Laravel 中文文档》</a></p>
</blockquote>
</div></template>


